package eolympics.server;

import java.util.List;

import jexxus.server.ConnectionToClient;
import jexxus.server.Server;
import data.GameData;
import data.GameState;
import data.IPlayerReadOnly;
import data.Player;

abstract class GameServerParentState
        implements IGameServerState
{
    private final String        REGEX_FOR_ONLY_LETTERS_AND_NUMBERS = "[^a-zA-Z0-9]";
    private final String        REGEX_FOR_TRAILING_NUMBERS         = "\\d*$";

    protected final Server      mServer;
    protected final GameData    mGameData;
    protected final IGameServer mGameServer;

    public GameServerParentState(final IGameServer pGameServer)
    {
        mGameServer = pGameServer;
        mServer = mGameServer.getServer();
        mGameData = mGameServer.getGameData();
    }

    @Override
    public void clientConnected( final ConnectionToClient pNewClient )
    {
        pNewClient.close();
    }

    @Override
    public void playerWantsToJoin( final Player pPlayerAskingToJoin )
    {
    }

    @Override
    public void playerIsReady( final Player pPlayerWhoIsReady )
    {
    }

    @Override
    public abstract GameState getGameState();

    @Override
    public void start()
    {
    }

    @Override
    public void addAiPlayer( final Player pAiPlayer )
    {
        throw new RuntimeException("Can not add ai to server in gamestate: " + getGameState());
    }

    @Override
    public void removeAiPlayer( final String pAiPlayerName )
    {
        throw new RuntimeException("Can not remove ai from server in gamestate: " + getGameState());
    }

    protected void addNewPlayerWithValidetNameAndInformClients( final Player pNewPlayer )
    {
        setUniqueName(pNewPlayer);

        mGameData.addPlayer(pNewPlayer);

        mGameServer.sendPlayerListChangedToClients();
    }

    protected void setUniqueName( final Player pNewPlayer )
    {
        String name = pNewPlayer.getName();
        String newName = name.replaceAll(REGEX_FOR_ONLY_LETTERS_AND_NUMBERS, "");

        if( newName.length() == 0 )
        {
            newName = "0";
        }

        List<IPlayerReadOnly> players = mGameData.getReadOnlyPlayerList();

        int suffix = 0;
        boolean hasDuplicateNameBeenFound = false;

        do
        {
            hasDuplicateNameBeenFound = false;
            for( IPlayerReadOnly currentPlayer : players )
            {
                String currentName = currentPlayer.getName();
                if( currentName.equals(newName) )
                {
                    newName = newName.replaceAll(REGEX_FOR_TRAILING_NUMBERS, "");
                    newName = newName + suffix;
                    suffix++;
                    hasDuplicateNameBeenFound = true;
                }
            }
        }
        while( hasDuplicateNameBeenFound );

        pNewPlayer.setName(newName);
    }

    protected boolean setPlayerReadyAndCheckIfAllPlayersAreReady( final Player pPlayerWhoIsReady )
    {
        boolean allPlayersReady = true;

        synchronized( mGameData.mPlayerListLock )
        {
            for( Player currentPlayer : mGameData.getPlayers() )
            {
                if( currentPlayer == pPlayerWhoIsReady )
                {
                    currentPlayer.setReady(true);
                }

                if( !currentPlayer.isReady() )
                {
                    allPlayersReady = false;
                }
            }
        }

        return allPlayersReady;
    }
}
